<template>
	<div class="system-menu-container layout-pd">
		<el-card shadow="hover">
			<div class="system-menu-search mb15">
				<el-row :gutter="20">
					<el-col :span="24" v-auth="'system:menu:query'">
						<el-input size="default" placeholder="请输入菜单名称" class="mt10" v-model="state.param.menuName" @keyup.enter.native="getTableData" />
						<el-select v-model="state.param.status" placeholder="菜单状态" clearable class="mt10" size="default" @change="getTableData">
							<el-option v-for="dict in sys_normal_disable" :key="dict.value" :label="dict.label"
								:value="dict.value" />
						</el-select>
						<el-button size="default" type="primary" class="mt10" @click="getTableData" :icon="'ele-Search'">
							查询
						</el-button>
						<el-button size="default" class="mt10" type="info" @click="resetParamData()" :icon="'ele-Refresh'">
							重置
						</el-button>
					</el-col>
					<el-col :span="24">
						<el-button size="default" type="success" class="mt10" @click="onOpenAddMenu('add', 0)" :icon="'ele-Plus'"
							v-auth="'system:menu:add'">
							新增菜单
						</el-button>
						<el-button size="default" type="primary" class="mt10" :icon="'ele-Sort'" @click="handleExpandAll">
							{{ state.tableData.handleExpandAll ? '折叠' : '展开' }}
						</el-button>
					</el-col>
				</el-row>
			</div>
			<el-table v-if="refreshTable" ref="tableRef" :data="state.tableData.data" v-loading="state.tableData.loading" style="width: 100%" row-key="menuId"
				border @row-click="onTabelRowClick" :default-expand-all="state.tableData.handleExpandAll"
				:expand-row-keys="expands" @expand-change="expandSelect"
				:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
				<el-table-column label="菜单名称" show-overflow-tooltip width="200">
					<template #default="scope">
						<SvgIcon :name="scope.row.icon" />
						<span class="ml10">{{ scope.row.menuName }}</span>
					</template>
				</el-table-column>
				<el-table-column prop="path" label="路由路径" show-overflow-tooltip></el-table-column>
				<el-table-column label="组件路径" show-overflow-tooltip>
					<template #default="scope">
						<span>{{ scope.row.component }}</span>
					</template>
				</el-table-column>
				<el-table-column prop="perms" label="权限标识" show-overflow-tooltip></el-table-column>
				<el-table-column prop="orderNum" label="排序" show-overflow-tooltip width="80">
				</el-table-column>
				<el-table-column prop="status" label="状态" width="80">
					<template #default="scope">
						<dict-tag :options="sys_normal_disable" :value="scope.row.status" />
					</template>
				</el-table-column>
				<el-table-column label="操作" show-overflow-tooltip width="140" fixed="right"
					v-auths="['system:menu:edit', 'system:menu:add', 'system:menu:remove']">
					<template #default="scope">
						<el-button size="small" text type="primary" v-auth="'system:menu:add'"
							@click="onOpenAddMenu('add', scope.row.parentId)">新增</el-button>
						<el-button size="small" text type="primary" @click="onOpenEditMenu('edit', scope.row)"
							v-auth="'system:menu:edit'">修改</el-button>
						<el-button size="small" text type="primary" @click="onTabelRowDel(scope.row)"
							v-auth="'system:menu:remove'">删除</el-button>
					</template>
				</el-table-column>
			</el-table>
		</el-card>
		<MenuDialog ref="menuDialogRef" @refresh="getTableData()" />
	</div>
</template>

<script setup lang="ts" name="systemMenu">
import { defineAsyncComponent, ref, onMounted, reactive, nextTick } from 'vue';
import { ElMessageBox, ElMessage } from 'element-plus';
import { useMenu } from '/@/api/system/menu';
import { handleTree } from '/@/utils/tool';
import { setBackEndControlRefreshRoutes } from '/@/router/backEnd';
import { useDict } from '/@/utils/dict';

const { sys_normal_disable } = useDict("sys_normal_disable");
const MenuDialog = defineAsyncComponent(() => import('/@/views/system/menu/dialog.vue'));

// 定义变量内容
const tableRef = ref();
const refreshTable = ref(true);
const expands = ref(<any>[]);
const menuDialogRef = ref();
const state = reactive({
	tableData: {
		handleExpandAll: false,
		data: [] as RowMenuType[],
		loading: true,
	},
	param: {
		menuName: '',
		status: '',
	},
});

/**
 *  获取路由数据, 并处理成树形结构
 * @Api /system/menu/listMenu
 * @handleTree 处理成树形结构 /@/utils/tool
 */
const getTableData = async () => {
	try {
		state.tableData.loading = true;
		const res = await useMenu().listMenu(state.param);
		state.tableData.data = handleTree(res.data, 'menuId', 'parentId', 'children');
	} catch (error) {
		ElMessage.error('获取数据失败');
		return Promise.reject(error);
	} finally {
		state.tableData.loading = false;
	}
};


/**
 * 打开新增菜单弹窗
 * @param type add/edit
 * @param row 当前行数据
 * @Api /system/menu/listMenu
 * @handleTree 处理成树形结构 /@/utils/tool
 */
const onOpenAddMenu = async (type: string, parentId: number) => {
	try {
		state.tableData.loading = true;
		menuDialogRef.value.openDialog(type, state.tableData.data, parentId);
	} catch (error) {
		ElMessage.error('打开弹窗失败');
		return Promise.reject(error);
	} finally {
		state.tableData.loading = false;
	}
};

/**
 * 打开编辑菜单弹窗
 * @param type
 * @param row
 * @Api /system/menu/listMenu
 * @handleTree 处理成树形结构 /@/utils/tool
 */
const onOpenEditMenu = async (type: string, row: RowMenuType) => {
	try {
		state.tableData.loading = true;
		menuDialogRef.value.openDialog(type, state.tableData.data, row.parentId, row);
	} catch (error) {
		ElMessage.error('打开弹窗失败');
		return Promise.reject(error);
	} finally {
		state.tableData.loading = false;
	}
};

/**
 * 删除菜单
 * @param row
 * @Api /system/menu/delMenu
 */
const onTabelRowDel = async (row: RowMenuType) => {
	try {
		await ElMessageBox.confirm(`此操作将永久删除路由：${row.path}, 是否继续?`, '提示', {
			confirmButtonText: '删除',
			cancelButtonText: '取消',
			type: 'warning',
		});
		const res = await useMenu().delMenu(row.menuId);
		if (res.code === 200) {
			getTableData();
			setBackEndControlRefreshRoutes();
		} else {
			ElMessage.error(res.msg);
		}
	} catch (error) {
		return Promise.reject(error);
	}
};
/**
 * 重置搜索数据
 */
const resetParamData = () => {
	state.param = {
		menuName: '',
		status: '',
	};
	getTableData();
};


/**
 * 列表行点击事件
 */
 const onTabelRowClick = (row: RowDeptType) => {
	tableRef.value.toggleRowExpansion(row);
};

/**
 * 展开/收起
 * @param row 当前行数据
 * @param expanded 是否展开
 */
const expandSelect = (row: RowDeptType, expanded: boolean) => {
	if (expanded) {
		expands.value.push(row.deptId);
	} else {
		const index = expands.value.findIndex((item: number) => item === row.deptId);
		expands.value.splice(index, 1);
	}
};

/**
 * 展开全部/收起全部
 */
const handleExpandAll = () => {
	refreshTable.value = false;
	state.tableData.handleExpandAll = !state.tableData.handleExpandAll;
	nextTick(() => {
		refreshTable.value = true;
	});
};


// 页面加载时
onMounted(() => {
	getTableData();
});
</script>
